Test Double
テストのための代用品
Mock ObjectやTest Stubなどの諸々の代用品の総称
DOCを代用する
SUTとDOCの依存の仕方によって分類している感じ
『xUnit Test Patterns』で定義された
前提として以下の2つを抑える
間接出力
「SUTが依存する関数」の引数
間接入力
「SUTが依存する関数」の返り値
大きく分けると2つ、小さく分けると5つある
SUTから外部へ向かうコミュニケーションを模倣し、検証するために使う
Post, Commandの方向mrsekut.icon
Mock Object
間接出力を受け取って、その検証も行う
Test Spy
SUTの間接出力を記録する
SUTに対して、内部へ向かうコミュニケーションを模倣するのに使われる
Get, Queryの方向mrsekut.icon
Test Stub
SUTへの間接入力を代替する
Dummy Object
テストに影響を与えない代替object
Fake Object
テストの範囲内で本物と同じように動作する
まだ存在しない依存を置き換える
分類は諸説ある
『xUnit Test Patterns』という本が、↑のような小分類をしているらしい
割と一般的になっているっぽい
test libraryが上記の分類に沿っていると理解が楽になる
例えばJSのsinonはこれに沿っているらしい ref
Jestは沿っていないので困惑するとのこと ref
以下の2つを混同しないようにする
ref /mrsekut-book-4839981728/151
道具としての「モック」
濫用される「モック」という言葉
libraryの命名などで雑に呼んでる「モック」のこと
test stubもmock objectも作れる
test doubleとしてのmock
mock object
Imposterパターン
/kawasima/Test Double
Mockをやめる
参考
/mrsekut-book-4839981728/149 (5.1 モックとスタブの違い)
xUnit Test PatternsのTest Doubleパターン(Mock、Stub、Fake、Dummy等の定義) - 千里霧中
簡潔でわかりやすい
よく引用されている記事
https://qiita.com/s_karuta/items/ee211251d944e72b2517#モックの用語整理とjestモックライブラリの位置づけ
https://twop.agile.esm.co.jp/are-stub-and-mock-really-bad-ed7658927ba7
test doubleのメンテは大変
#WIP
Mock ObjectとTest Stubの違い
↓こういう感じか?
こういう関数をテストしたいときに
code:ts
const sut = () => {
.. // ①
const r = ex(x)
.. // ②
}
ex()が外部の関数である
このとき、ex()が特定の値を返すように設定してテストを行うのがTest Stub
良い感じの返り値を返してくれるex()をtest stubと呼ぶ
ex()の返り値(間接入力)を代替している
ここで検証したいのは、rの値を固定した上でのその他の処理
雑に捉えるなら②の部分の処理
このとき、xをちゃんと作れているかを検証するために使うのがMock Object
Mock Object内にテストコードを書いてる感じ?
ここで検証したいのは、xの作り方部分
雑に捉えるなら①の部分の処理
これだけ見ると、①の部分を別の関数に切り出せばMock Objectという概念が不要にならん?
両方の性質を持ったtest doubleもある
/mrsekut-book-4839981728/154
そういう場合は「モック」と呼ばれる事が多い
雑すぎん?
Mock ObjectとTest Spyの違い
両方とも間接出力を検証する
Mock Objectは、Mock Object内で間接出力結果を評価する
Test Spyは間接出力を保持するだけで、間接出力結果の評価は後からテストコード上で行う
Mock Objectの立ち位置かなり異様じゃない?
もはや並列概念ですら無い気もする
Test SpyとTest Stubの違い
多くの場合、両方の性質を持ったものを使うことが多くない?mrsekut.icon